<!DOCTYPE html>
<html>
	<head>
		<title>Deferred Shading</title>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<link rel="stylesheet" href="webgl.css" type="text/css">
		<script src="jquery-1.4.2.min.js" type="text/javascript"></script>
		<script src="SmitearWebGL/utils/stats.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/basic.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/BaseClass.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/referencecounter.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/geometry/geometry.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/geometry/vertex.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/geometry/triangle.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/geometry/edge.js" type="text/javascript"></script>
		<script src="SmitearWebGL/events/eventdispatcher.js" type="text/javascript"></script>
		<script src="SmitearWebGL/resources/resourceItem.js" type="text/javascript"></script>
		<script src="SmitearWebGL/resources/resourcePool.js" type="text/javascript"></script>
		<script src="SmitearWebGL/resources/resourcemanager.js" type="text/javascript"></script>
		<script src="SmitearWebGL/resources/surfacematerial.js" type="text/javascript"></script>
		<script src="SmitearWebGL/resources/materiallayer.js" type="text/javascript"></script>
		<script src="SmitearWebGL/resources/rendersurface.js" type="text/javascript"></script>
		<script src="SmitearWebGL/resources/buffer.js" type="text/javascript"></script>
		<script src="SmitearWebGL/resources/shader.js" type="text/javascript"></script>
		<script src="SmitearWebGL/resources/vertexbuffer.js" type="text/javascript"></script>
		<script src="SmitearWebGL/resources/indexbuffer.js" type="text/javascript"></script>
		<script src="SmitearWebGL/resources/texture.js" type="text/javascript"></script>
		<script src="SmitearWebGL/resources/texture2d.js" type="text/javascript"></script>
		<script src="SmitearWebGL/resources/texturecube.js" type="text/javascript"></script>
		<script src="SmitearWebGL/scene/scene.js" type="text/javascript"></script>
		<script src="SmitearWebGL/objects/viewport.js" type="text/javascript"></script>
		<script src="SmitearWebGL/objects/light.js" type="text/javascript"></script>
		<script src="SmitearWebGL/objects/camera.js" type="text/javascript"></script>
		<script src="SmitearWebGL/objects/entity.js" type="text/javascript"></script>
		<script src="SmitearWebGL/objects/mesh.js" type="text/javascript"></script>
		<script src="SmitearWebGL/objects/shadowmesh.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/render/dsrenderer.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/render/framebufferobject.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/render/technique/shadertechnique.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/render/technique/basemaptechnique.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/render/technique/normaltechnique.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/render/technique/shadowtechnique.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/render/technique/depthtechnique.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/render/technique/deferredshading/lightprocessingtechnique.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/render/technique/deferredshading/postprocessingtechnique.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/render/technique/deferredshading/specprocessingtechnique.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/render/technique/deferredshading/ambiprocessingtechnique.js" type="text/javascript"></script>
		<script src="SmitearWebGL/core/render/technique/deferredshading/colorprocessingtechnique.js" type="text/javascript"></script>
		<script src="SmitearWebGL/objects/special/deferredshading/lightprocessingcanvas.js" type="text/javascript"></script>
		<script src="SmitearWebGL/objects/special/deferredshading/postprocessingcanvas.js" type="text/javascript"></script>
		<script src="SmitearWebGL/objects/primitive/plane.js" type="text/javascript"></script>
		<script src="SmitearWebGL/objects/primitive/teapot.js" type="text/javascript"></script>
		<script src="SmitearWebGL/objects/primitive/torus.js" type="text/javascript"></script>
		<script src="SmitearWebGL/objects/primitive/sphere.js" type="text/javascript"></script>
		<script src="SmitearWebGL/objects/primitive/skybox.js" type="text/javascript"></script>
		<script src="SmitearWebGL/objects/primitive/cube.js" type="text/javascript"></script>
		<script src="SmitearWebGL/objects/external/dae.js" type="text/javascript"></script>
		<script src="SmitearWebGL/objects/parser/collada/daereader.js" type="text/javascript"></script>
		<script type="text/javascript">
			var o1, sky, scene, viewport, camera, material, material2, layer, texture;
			var lights = [], lSpheres = [], defaultNumLights = 1, path, nt = 0;
			var normalTex;
			var degree = 0;
			var frameBuf;
			var renderBuf;

			function StartWebGL()
			{
				document.getElementById("numLights").value = defaultNumLights;
				
				SmitearWebGL.createWebGLCanvas( "smiteargl", "glcanvas", "gl-css shadow", 200 );
				SmitearWebGL.createWebGLStats( "stats", "glstats", "stats-css" );
				
				scene = new SmitearWebGL.Scene.Scene();
				
				camera = new SmitearWebGL.Objects.Camera("camera", 45.0, $GL.displayInfo.width / $GL.displayInfo.height, 0.1, 1000);
				camera.setX(0);
				camera.setY(0);
				camera.setZ(5);
				camera.setTarget($V3(0.0, 0.0, 0.0));

				viewport = new SmitearWebGL.Objects.Viewport(0, 0, $GL.displayInfo.width, $GL.displayInfo.height);
				
				path = new SmitearWebGL.Objects.Entity( "trace" );
				path.setZ(0);
				scene.addChild(path);
				
				addLights(defaultNumLights);
				setupMaterial();
				
//				o1 = new SmitearWebGL.Objects.Primitive.TorusKnot("TorusKnot", 30, 16, 1, 1, .2);
//				o1 = new SmitearWebGL.Objects.Primitive.Sphere("Sphere", 16, 12, 1);
//				o1 = new SmitearWebGL.Objects.Primitive.Torus("Torus", 12, 12, 1, .5);
//				o1 = new SmitearWebGL.Objects.Primitive.Plane("Plane", 2, 2, 2, 2);
//				o1 = new SmitearWebGL.Objects.Primitive.Cube("Cube", 2, 2, 2, 1, 1);
				o1 = new SmitearWebGL.Objects.Primitive.Teapot("Teapot");
//				o1 = new SmitearWebGL.Objects.External.Dae("dae");
//				o1.load("media/teapot.DAE");
				o1.material = material;
				o1.setScale(.1);
				o1.setRotationX(25);
				scene.addChild(o1);
//				o1.generateShadowMesh();
				
				sky = new SmitearWebGL.Objects.Primitive.SkyBox("skybox");
				sky.backFaceCulling = true;
				sky.material = material2;
				sky.setScale(5);
				sky.setZ(0);
				scene.addChild(sky);
				
				document.onmousedown = handleMouseDown;
				document.onmouseup = handleMouseUp;
				document.onmousemove = handleMouseMove;
				document.onkeydown = handleKeyDown;
				document.onkeyup = handleKeyUp;
				
//				scene.enableShadowCasting();
//				scene.showShadowVolume( true );
				scene.render(viewport, camera);
			}
			
			function addLights(numLights)
			{
				var handle;
				var light;
				var lSphere;
				var lMat;
				
				for ( var i = 0; i < numLights; ++ i )
				{
					var rnd =  Math.random().toString();
					
					handle = g_lightManager.createResource("light_" + nt);
					light = g_lightManager.getResourceByHandle(handle);
					light.type = SmitearWebGL.Objects.Light.L_SPOT;
					light.baseColor = $C(Math.random(), Math.random(), Math.random(), 1.0);
					light.ambient = 0.2;
					light.diffuse = 1.0;
					light.specular = 1.0;
					light.constantAttenuation = 0.5;
					light.linearAttenuation = 0.005;
					light.quadraticAttenuation = 0.001;
					light.setY(4);
//					light.setX(getRandom(1.5, 3.0));
//					light.setY(getRandom(1.5, 3.0));
//					light.setZ(getRandom(1.5, 3.0));
					light.spotExponent = 32;
					light._spotCosCutOff = 0.92;
					light.randomDirection = getRandom(0.5, 1.0);
					path.addChild(light);
					lights.push(light);
					
					handle = g_materialManager.createResource("__light_material__" + nt);
					lMat = g_materialManager.getResourceByHandle(handle);
					lMat.baseColor = light.baseColor;
					lMat.ambient = 1.0;
					lMat.diffuse = 1.0;
					lMat.specular = 0.0;
					
					var lSphere = new SmitearWebGL.Objects.Primitive.Sphere("__light_entity__" + nt, 8, 8, .05);
					lSphere.material = lMat;
					lSphere.backFaceCulling = true;
					lSphere.setX( light.getX() );
					lSphere.setY( light.getY() );
					lSphere.setZ( light.getZ() );
					path.addChild(lSphere);
					lSpheres.push(lSphere);
					
					nt ++;
				}
			}
			
			function removeLights(numLights)
			{
				if ( numLights > lights.length )
					numLights = lights.length;
				
				var total = lights.length - 1;
				var end = lights.length - numLights;
					
				for ( var i = total; i >= end; -- i )
				{
					path.removeChild(lights[i]);
					path.removeChild(lSpheres[i]);
					lights.pop().release();
					lSpheres.pop().release();
				}
			}
			
			function getRandom(a, b)
			{
				var result = Math.random() * b + a;
				var rd = Math.random();
				if ( rd > .5)
					return result;
				else
					return - result;
			}
			
			function setupMaterial()
			{
				var handle;
				
				handle = g_samplerManager.createResource("sampler");
				var sampler = g_samplerManager.getResourceByHandle(handle);
				
				handle = g_materialManager.createResource("material");
				material = g_materialManager.getResourceByHandle(handle);
				material.ambient = 0.2;
				material.diffuse = 0.6;
				material.specular = 0.8;
				material.emissive = 0.0;
				material.shininess = 32.0;
				
				handle = g_texture2dManager.loadResource("media/wood01.jpg");
				texture = g_texture2dManager.getResourceByHandle(handle);
				texture.bindSampler(sampler);

				handle = g_materialLayerManager.createResource("materialLayer2");
				layer = g_materialLayerManager.getResourceByHandle(handle);
				layer.mapinput = SmitearWebGL.Resources.MaterialLayer.UV1;
				layer.setTexture(texture);
				material.addLayer(layer);
				
				handle = g_texture2dManager.loadResource("media/cubetexture.png");
				texture = g_texture2dManager.getResourceByHandle(handle);
				texture.bindSampler(sampler);

				handle = g_materialLayerManager.createResource("materialLayer3");
				layer = g_materialLayerManager.getResourceByHandle(handle);
				layer.mapinput = SmitearWebGL.Resources.MaterialLayer.UV1;
				layer.setTexture(texture);
				material.addLayer(layer);
				
				//
				handle = g_textureCubeManager.loadResource("media/cubemap/CubemapCross.png");
				texture = g_textureCubeManager.getResourceByHandle(handle);
				texture.bindSampler(sampler);
				
				handle = g_materialLayerManager.createResource("materialLayer");
				layer = g_materialLayerManager.getResourceByHandle(handle);
				layer.mapinput = SmitearWebGL.Resources.MaterialLayer.UV1;
				layer.setTexture(texture);
				
				handle = g_materialManager.createResource("material2");
				material2 = g_materialManager.getResourceByHandle(handle);
//				material2.baseColor = $C(1.0, 1.0, 0.0, 1.0);
				material2.ambient = 0.2;
				material2.diffuse = 0.8;
				material2.specular = 0.8;
				material2.shininess = 32.0;
				material2.doublaSide = false;
				material2.addLayer(layer);
				
//				$("#control")[0].appendChild(texture.getHtmlElement());
			}
			
			//////////////////////////////// frame moving //////////////////////////////
			
			function onFrameMoving()
			{
				degree = (new Date()).valueOf() / 40;
//				o1.set//tationY(degree);
//				o1.set//tationX(degree);
//				o1.set//tationZ(degree);
				
				for ( var i = 0; i < lights.length; ++ i )
				{
					var light = lights[i];
					var degree2 = degree * light.randomDirection;
					light.setRotationX(degree2);
					light.setRotationY(degree2);
					light.setRotationZ(degree2);
				}
			}
			
			//////////////////////////////// interactive //////////////////////////////
			
			var mouseDown = false;
			var lastMouseX = 0, lastMouseY = 0;

			function handleMouseDown(event)
			{
				mouseDown = true;
				lastMouseX = event.clientX;
				lastMouseY = event.clientY;
			}

			function handleMouseUp(event)
			{
				mouseDown = false;
			}

			function handleMouseMove(event)
			{
				if ( mouseDown )
				{
					var newX = event.clientX;
					var newY = event.clientY;
					
					var mouseX = (newX - lastMouseX) * 0.05;
					var mouseY = (newY - lastMouseY) * 0.05;
					camera.setY(camera.getY() + mouseY);
					camera.setX(camera.getX() + mouseX);
					
					lastMouseX = newX;
					lastMouseY = newY;
				}
			}
			
			var currentlyPressedKeys = Object();
			
			function handleKeyDown(event)
			{
				currentlyPressedKeys[event.keyCode] = true;
			
				if (String.fromCharCode(event.keyCode) == "s")
				{
					scene.stopRendering();
				}
			}

			function handleKeyUp(event)
			{
				currentlyPressedKeys[event.keyCode] = false;
			}
			
			function btnDec_click()
			{
				var elem = document.getElementById("numLights");
				var num = parseInt(elem.value);
				if ( num == 0 ) return;
				-- num;
				elem.value = num.toString();
				
				removeLights( 1 );
			}
			
			function btnInc_click()
			{
				var elem = document.getElementById("numLights");
				var num = parseInt(elem.value);
				if ( num == 255 ) return;
				++ num;
				elem.value = num.toString();
				
				addLights( 1 );
			}
			
			function numLights_chnage(value)
			{
				var numToAddOrDel = value - lights.length;
				if ( numToAddOrDel > 0 )
				{
					addLights(numToAddOrDel);
				}
				else
				{
					removeLights(-numToAddOrDel);
				}
			}
		</script>
	</head>
	<body>
		<div class="webglContent">
			<div id="stats"></div>
			<div id="smiteargl"></div>
		</div>
		<div id="control">
			灯光数量: 
			<button type="button" id="btnDec" onclick="btnDec_click();">-</button>
			<input id="numLights" value="0" style="width:20px;" onchange="numLights_chnage(parseInt(this.value));"></input>
			<button type="button" id="btnInc" onclick="btnInc_click();">+</button>
		</div>
	</body>
</html>
